package bayes;

import engine.Stats;
import engine.Tweet;
import engine.Tweet.Brand;
import engine.Tweet.Polarity;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;
import normalisation.Normalizer;
import utilities.FileTools;

public class Classifieur implements IClassifieur {

    protected ArrayList<Tweet> lstTweet;
    protected TreeMap<String, Integer>[] tfMapsPolarity;//tf maps de chaque classe pour le calcul de vraisemblance
    protected TreeMap<String, Integer>[] tfMapsBrand;
    protected TreeMap<String, Integer> dictionnaire;
    protected Normalizer normalizer;
    protected int nbDoc;
    protected double[] aPrioris;
    protected int[] tailleVoc;

    public Classifieur() {
        lstTweet = new ArrayList<Tweet>();
        dictionnaire = new TreeMap<String, Integer>();
        tfMapsPolarity = new TreeMap[Polarity.values().length];
        tfMapsBrand = new TreeMap[Brand.values().length];
        for (int i = 0; i < Polarity.values().length; i++) {
            tfMapsPolarity[i] = new TreeMap<String, Integer>();
        }

        for (int i = 0; i < Brand.values().length; i++) {
            tfMapsBrand[i] = new TreeMap<String, Integer>();
        }
        aPrioris = new double[Polarity.values().length];
        tailleVoc = new int[aPrioris.length];
        for (int i = 0; i < aPrioris.length; i++) {
            aPrioris[i] = 0.;
            tailleVoc[i] = 0;
        }
    }

    @Override
    public void train(String trainPath, Normalizer normalizer) {
        //System.out.println("Training...");
        try {
            this.normalizer = normalizer;
            List<String> lines = FileTools.readLinesTextFile(trainPath, normalizer.getCharset());
            //System.out.println("Fichier d'entrainement : " + trainPath);
            Polarity currentPolarity;
            Brand currentBrand;
            for (String line : lines) {
            
                Tweet tweet = new Tweet();
                //suppression première parenthèse (doit être le premier caractère)
                line = line.substring(1);

                //parse la polarité
                currentPolarity = Stats.parsePolarity(line.substring(0, line.indexOf(",")));
                tweet.setPolarity(currentPolarity);
                line = line.substring(line.indexOf(",") + 1);//on supprime "polarité,"

                //parse la marque
                currentBrand = Stats.parseBrand(line.substring(0, line.indexOf(")")));
                tweet.setBrand(currentBrand);
                line = line.substring(line.indexOf(")") + 2);//on supprime "marque) "

                tweet.setContenu(line);
                lstTweet.add(tweet);
            }
        } catch (IOException ioe) {
        }
        //System.out.println("Creation map...");
        makeMap(normalizer);

        //System.out.println("...done.");
    }

    /**
     * Méthode permettant de construire les map de polarité et de marque en
     * fonction de la méthode de normalisation choisie. Ces deux map sont
     * construites à partir de la liste de tweet préalablement remplie via la
     * méthode train.
     *
     * @param normalizer : objet représentant les méthodes de normalisation que
     * l'on souhaite mettre en place
     */
    protected void makeMap(Normalizer normalizer) {
        for (Tweet tweet : lstTweet) {
            
            ArrayList<String> lstMots = normalizer.normalize(tweet.getContenu());
            TreeMap<String, Integer> mapBrand = tfMapsBrand[tweet.getBrand().ordinal()];
            TreeMap<String, Integer> mapPolarity = tfMapsPolarity[tweet.getPolarity().ordinal()];
            for (String word : lstMots) {
                mapPolarity.put(word, (mapPolarity.containsKey(word) ? mapPolarity.get(word) + 1 : 1));
                dictionnaire.put(word, dictionnaire.containsKey(word) ? dictionnaire.get(word) + 1 : 1);
                tailleVoc[tweet.getPolarity().ordinal()] += 1;
            }
            aPrioris[tweet.getPolarity().ordinal()] += 1.;
        }
        
        nbDoc = lstTweet.size();
        for (int i = 0; i < aPrioris.length; i++) {
            aPrioris[i] /= (double) nbDoc;
        }
        if (normalizer.getFilterOneOccurence()) {
            supprimerOccurencesUniques();
        }
    }

    public ArrayList<Integer> determinerPolarite(ArrayList<Tweet> listOfTweet) {
        return null;
    }

    protected void supprimerOccurencesUniques() {
        ArrayList<String> listStr = new ArrayList<String>();
        for (String word : dictionnaire.keySet()) {
            listStr.add(word);
        }
        for (String word : listStr) {
            if (dictionnaire.get(word) == 1) {
                dictionnaire.remove(word);
            }
        }
    }
}
